package com.probox.common.entity.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.UUID;

/**
 * @author Kite
 * @date 2021/7/10
 */
public class ImgUploadingUtil {
    //服务商商户ID
    private final static String mchid = "1609865431";

    //商户序列号
    private final static String serize_no = "48D64E15280430B7DE58E92841F0CAA7B18D9F2A";

    public static JSONObject imgUploading(File file, String uploadUrl) throws Exception {
        FileInputStream ins1 = new FileInputStream(file);
        String sha256 = DigestUtils.sha256Hex(ins1);

        long timestamp = System.currentTimeMillis() / 1000;
        String nonce_str = UUID.randomUUID().toString().replace("-", "");
        //拼签名串
        StringBuffer sb = new StringBuffer();
        sb.append("POST").append("\n");
        sb.append("/v3/merchant/media/upload").append("\n");
        sb.append(timestamp).append("\n");
        sb.append(nonce_str).append("\n");
        sb.append("{\"filename\":\"" + file.getName() + "\",\"sha256\":\"" + sha256 + "\"}").append("\n");
        System.out.println("签名原串:" + sb.toString());
        //计算签名
        String sign1 = sign(sb.toString().getBytes("UTF-8"), mchid);
        System.out.println("签名sign值:" + sign1);

        //拼装http头的Authorization内容
        String authorization = "WECHATPAY2-SHA256-RSA2048 mchid=\"" + mchid + "\",nonce_str=\"" + nonce_str + "\",signature=\"" + sign1 + "\",timestamp=\"" + timestamp + "\",serial_no=\"" + serize_no + "\"";
        System.out.println("authorization值:" + authorization);


        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(uploadUrl);

        //设置头部
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-Type", "multipart/form-data");
        httpPost.addHeader("Authorization", authorization);

        //创建MultipartEntityBuilder
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
        //设置boundary
        multipartEntityBuilder.setBoundary("11111111");
        multipartEntityBuilder.setCharset(Charset.forName("UTF-8"));
        //设置meta内容
        multipartEntityBuilder.addTextBody("meta", "{\"filename\":\"" + file.getName() + "\",\"sha256\":\"" + sha256 + "\"}", ContentType.APPLICATION_JSON);
        //设置图片内容
        multipartEntityBuilder.addBinaryBody("file", file, ContentType.create("image/jpg"), file.getName());
        //放入内容
        httpPost.setEntity(multipartEntityBuilder.build());
        //获取返回内容
        CloseableHttpResponse response = null;
        HttpEntity httpEntity = null;
        String resultStr = null;
        try {
            response = httpclient.execute(httpPost);
            httpEntity = response.getEntity();
            resultStr = EntityUtils.toString(httpEntity, "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }


        return JSONObject.parseObject(resultStr);
    }



    /**
     * 生成签名
     *
     * @param message            请求体
     * @return 生成base64位签名信息
     * @throws Exception
     */
    static String sign(byte[] message, String mercId) throws Exception {
        Signature sign = Signature.getInstance("SHA256withRSA");
        CertHelper certHelper = new CertHelper();
        PrivateKey privateKey = certHelper.createPKCS12(mercId).getPrivate();
        sign.initSign(privateKey);
        sign.update(message);
        return Base64.getEncoder().encodeToString(sign.sign());
    }
}
